package org.digitarts.rtms.tracing

import java.util.Date
import java.util.Map
import java.util.HashMap

import org.digitarts.rtms.tracing.ITracer;

import org.digitarts.rtms.tracing.threads.ThreadInfoCapture
import com.wily.introscope.agent.api.DataRecorderFactory

/**
 * @author zhanghuabin
 *
 */
class IntroscopeTracer implements ITracer
{

	def oldValues = [:]
//	Map<String, Long> oldValues = new HashMap<String, Long>()
	
	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#trace(int, java.lang.String...)
	 */
	void trace(int value, String... name){
		DataRecorderFactory.createIntAverageDataRecorder(getMetricName(name)).recordDataPoint(value)
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#trace(long, java.lang.String...)
	 */
	void trace(long value, String... name){
		DataRecorderFactory.createLongAverageDataRecorder(getMetricName(name)).recordDataPoint(value)
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#trace(java.lang.String, java.lang.String...)
	 */
	void trace(String value, String... name){
		DataRecorderFactory.createStringEventDataRecorder(getMetricName(name)).recordDataPoint(value)
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#trace(java.util.Date, java.lang.String...)
	 */
	void trace(Date value, String... name){
		// TODO Auto-generated method stub
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#traceSticky(int, java.lang.String...)
	 */
	void traceSticky(int value, String... name){
		DataRecorderFactory.createIntCounterDataRecorder(getMetricName(name)).recordCurrentValue(value)
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#traceSticky(long, java.lang.String...)
	 */
	void traceSticky(long value, String... name){
		DataRecorderFactory.createLongCounterDataRecorder(getMetricName(name)).recordCurrentValue(value)
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#traceDelta(int, java.lang.String...)
	 */
	void traceDelta(int value, String... name){
		// TODO Auto-generated method stub
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#traceDelta(long, java.lang.String...)
	 */
	void traceDelta(long value, String... name){
		// TODO Auto-generated method stub
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#traceDeltaSticky(int, java.lang.String...)
	 */
	void traceDeltaSticky(int value, String... name){
		traceDeltaSticky((long) value, name)
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#traceDeltaSticky(long, java.lang.String...)
	 */
	void traceDeltaSticky(long value, String... name){
		def metricName = getMetricName(name)
		int delta = getDelta(value, metricName)
		if (delta > 0)
		{
			DataRecorderFactory.createPerIntervalCounterDataRecorder(metricName).recordMultipleIncidents(delta)
		}
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#traceIncident(java.lang.String...)
	 */
	void traceIncident(String... name){
		// TODO Auto-generated method stub
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#traceIncident(int, java.lang.String...)
	 */
	void traceIncident(int value, String... name){
		// TODO Auto-generated method stub
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#trace(java.lang.String, java.lang.String, java.lang.String...)
	 */
	void trace(String value, String type, String... name){
		switch (type)
		{
			case METRIC_TYPE_LONG:
				trace((long) Long.valueOf(value), name)
				break
			case METRIC_TYPE_INT:
				trace((int) Integer.valueOf(value), name)
				break
			case METRIC_TYPE_STRING:
				trace((String) value, name)
				break
			case METRIC_TYPE_COUNTER_LONG:
				traceSticky((long) Long.valueOf(value), name)
				break
			case METRIC_TYPE_COUNTER_INT:
				traceSticky((int) Integer.valueOf(value), name)
				break
			case METRIC_TYPE_INCIDENT:
				traceIncident((int) Integer.valueOf(value), name)
				break
			case METRIC_TYPE_DELTA_INT:
				traceDelta((int) Integer.valueOf(value), name)
				break
			case METRIC_TYPE_DELTA_LONG:
				traceDelta((long) Long.valueOf(value), name)
				break
			case METRIC_TYPE_DELTA_STICKY_INT:
				traceDeltaSticky((int) Integer.valueOf(value), name)
				break
			case METRIC_TYPE_DELTA_STICKY_LONG:
				traceDeltaSticky((long) Long.valueOf(value), name)
				break
		}
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#startThreadInfoCapture(int)
	 */
	void startThreadInfoCapture(int options){
		// TODO Auto-generated method stub
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#startThreadInfoCapture(int, boolean)
	 */
	void startThreadInfoCapture(int options, boolean nanoTime){
		// TODO Auto-generated method stub
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#endThreadInfoCapture(java.lang.String...)
	 */
	ThreadInfoCapture endThreadInfoCapture(String... name){
		// TODO Auto-generated method stub
		return null
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#lookupRange(java.lang.String, long)
	 */
	String lookupRange(String rangeName, long value){
		// TODO Auto-generated method stub
		return null
	}

	/* (non-Javadoc)
	 * @see org.runtimemonitoring.tracing.ITracer#sizeOf(java.lang.Object)
	 */
	long sizeOf(Object obj){
		// TODO Auto-generated method stub
		return 0
	}

	private String getMetricName(String... name)
	{
//		def nameSpaceList = name - name[name.length-1]
		def nameSpace = new String[name.length-1]
		System.arraycopy(name, 0, nameSpace, 0, nameSpace.length)
		nameSpace.join("|")+":"+name[name.length-1]
	}

	private long getDelta(long newValue, String key)
	{
		def delta = oldValues.containsKey(key) ? newValue - oldValues[key] : 0
		oldValues[key] = newValue
		return delta
	}


}
